package com.aplink.generic.widgets.custom;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.KeyListener;
import android.text.method.PasswordTransformationMethod;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

import com.aplink.generic.adapter.ConfigAdapter;
import com.aplink.sg.R;

public class FloatingAutoComplete extends LinearLayout implements TextWatcher,
		View.OnTouchListener, Animator.AnimatorListener, OnFocusChangeListener {
	private AutoCompleteTextView mAutoCompleteTextView;
	private Button mShowAllButton;
	private TextView mLabel;
	private Animation bottomUp, bottomDown;

	public FloatingAutoComplete(Context context) {
		super(context);
		init(null, 0);
	}

	public FloatingAutoComplete(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs, 0);
	}

	public FloatingAutoComplete(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		init(attrs, defStyle);
	}

	private void init(AttributeSet attrs, int defStyle) {
		bottomUp = AnimationUtils.loadAnimation(getContext(),
				R.anim.txt_bottom_up);
		bottomDown = AnimationUtils.loadAnimation(getContext(),
				R.anim.txt_bottom_down);
		setOrientation(LinearLayout.VERTICAL);
		mLabel = new TextView(getContext());
		float paddingLeft = TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 10, getResources()
						.getDisplayMetrics());
		float paddingTop = TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 5, getResources()
						.getDisplayMetrics());
		mLabel.setPadding((int) paddingLeft, (int) paddingTop, 0, 0);
		mLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
		mLabel.setTextColor(Color.parseColor("#FFAAAAAA"));
		mLabel.setVisibility(View.INVISIBLE);
		mLabel.setAllCaps(true);
		FrameLayout frameLayout = new FrameLayout(getContext());
		mAutoCompleteTextView = new AutoCompleteTextView(getContext());
		mAutoCompleteTextView.setPadding((int) TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
						.getDisplayMetrics()), 0, 0, 0);
		mShowAllButton = new Button(getContext());
		mShowAllButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				mAutoCompleteTextView.showDropDown();
			}
		});
		FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
				FrameLayout.LayoutParams.MATCH_PARENT,
				FrameLayout.LayoutParams.WRAP_CONTENT);
		frameLayout.addView(mAutoCompleteTextView, layoutParams);

		float with = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30,
				getResources().getDisplayMetrics());
		float height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
				30, getResources().getDisplayMetrics());
		layoutParams = new FrameLayout.LayoutParams((int) with, (int) height);
		float btnShowPaddingLeft = TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 10, getResources()
						.getDisplayMetrics());
		layoutParams.setMargins((int) btnShowPaddingLeft, 0, 0, 0);
		frameLayout.addView(mShowAllButton, layoutParams);

		LinearLayout.LayoutParams params = new LayoutParams(
				LinearLayout.LayoutParams.MATCH_PARENT,
				LayoutParams.WRAP_CONTENT);
		addView(mLabel, params);
		addView(frameLayout, params);
		initTypeArray(attrs);

		mObjectAnimator = ObjectAnimator.ofFloat(this, "touchRadius", 0f, 0f);
		mObjectAnimator2 = ObjectAnimator.ofFloat(this, "touchRadius", 0f, 0f);
		mObjectAnimator.addListener(this);
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(Color.parseColor("#33B5E5"));
		paint.setAlpha(80);
		setEvents();
	}

	float mTouchX;
	private float touchRadius;
	private ObjectAnimator mObjectAnimator, mObjectAnimator2;
	private Paint paint = null;
	private String mHint;
	boolean isLabelShowing;

	@SuppressWarnings("deprecation")
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
	private void initTypeArray(AttributeSet attrs) {
		TypedArray typedArray = getContext().obtainStyledAttributes(attrs,
				R.styleable.FloatingAutoComplete, 0, 0);
		Drawable drawable = typedArray
				.getDrawable(R.styleable.FloatingAutoComplete_showAllIcon);
		if (Build.VERSION.SDK_INT == 15) {
			mShowAllButton.setBackgroundDrawable(drawable);
		} else {
			mShowAllButton.setBackground(drawable);
		}
		if (typedArray.getBoolean(
				R.styleable.FloatingAutoComplete_disableShowAllButton, true)) {
			mShowAllButton.setVisibility(View.GONE);
		}
		mHint = typedArray.getString(R.styleable.FloatingAutoComplete_hint);
		mAutoCompleteTextView.setHint(mHint);
		mLabel.setText(mHint);
		typedArray.recycle();
	}

	private void setEvents() {
		mAutoCompleteTextView.addTextChangedListener(this);
		mAutoCompleteTextView.setOnTouchListener(this);
		mAutoCompleteTextView.setOnFocusChangeListener(this);
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {

	}

	private void showHint() {
		mLabel.setText(mHint);
		mLabel.startAnimation(bottomUp);
		mLabel.setVisibility(View.VISIBLE);
		isLabelShowing = true;
	}

	private void disableHint() {
		mLabel.startAnimation(bottomDown);
		mLabel.setVisibility(View.INVISIBLE);
		isLabelShowing = false;
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		if (TextUtils.isEmpty(mAutoCompleteTextView.getText())) {
			disableHint();
		} else if (mAutoCompleteTextView.getText().length() >= 1
				&& !isLabelShowing) {
			showHint();
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.drawCircle(mTouchX,
				getHeight() - (getHeight() - mLabel.getHeight()) / 2,
				touchRadius, paint);
	}

	@Override
	public void afterTextChanged(Editable editable) {

	}

	@Override
	public boolean onTouch(View view, MotionEvent motionEvent) {
		if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
			mTouchX = motionEvent.getX();
			mObjectAnimator.setFloatValues(touchRadius, getHeight() / 2f);
			mObjectAnimator.setDuration(100);
			mObjectAnimator.start();
		}
		return false;
	}

	public float getTouchRadius() {
		return touchRadius;
	}

	public void setTouchRadius(float touchRadius) {
		this.touchRadius = touchRadius;
		this.invalidate();
	}

	@Override
	public void onAnimationStart(Animator animator) {

	}

	@Override
	public void onAnimationEnd(Animator animator) {
		mObjectAnimator2.setFloatValues(touchRadius, 0);
		mObjectAnimator2.setDuration(100);
		mObjectAnimator2.start();
	}

	@Override
	public void onAnimationCancel(Animator animator) {

	}

	@Override
	public void onAnimationRepeat(Animator animator) {

	}

	public Editable getText() {
		return mAutoCompleteTextView.getText();
	}

	public void setText(CharSequence editable) {
		mAutoCompleteTextView.setText(editable);
	}

	public void setText(String editable) {
		mAutoCompleteTextView.setText(editable);
	}

	public void setHint(String hint) {
		mAutoCompleteTextView.setHint(hint);
		mHint = hint;
	}

	public CharSequence getHint() {
		return mAutoCompleteTextView.getHint();
	}

	public void setInputType(int inputType) {
		mAutoCompleteTextView.setInputType(inputType);
	}

	public void setCursorVisible(boolean visible) {
		mAutoCompleteTextView.setCursorVisible(visible);
	}

	public void setTransformationMethod(PasswordTransformationMethod method) {
		mAutoCompleteTextView.setTransformationMethod(method);
	}

	public void setSingleLine(boolean visible) {
		mAutoCompleteTextView.setSingleLine(visible);
	}

	public void setFilters(InputFilter[] inputFilters) {
		mAutoCompleteTextView.setFilters(inputFilters);
	}

	public void setKeyListener(KeyListener input) {
		mAutoCompleteTextView.setKeyListener(input);
	}

	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		if (mFocusChange != null) {
			mFocusChange.onFocusChange(v, hasFocus);
		}
		if (hasFocus) {
			mLabel.setTextColor(Color.parseColor("#0099CC"));
		} else {
			if (mLabel.getVisibility() == View.VISIBLE) {
				mLabel.setTextColor(Color.parseColor("#FFAAAAAA"));
			}
		}
	}

	public AutoCompleteTextView getEditText() {
		return mAutoCompleteTextView;
	}

	@Override
	public void setEnabled(boolean enabled) {
		mAutoCompleteTextView.setEnabled(enabled);
		mAutoCompleteTextView.setFocusable(enabled);
	}

	private boolean isReadOnly;

	public void setReadOnly(boolean isReadOnly) {
		this.isReadOnly = isReadOnly;
		mAutoCompleteTextView.setCursorVisible(isReadOnly);
		mAutoCompleteTextView.setFocusable(isReadOnly);
		mAutoCompleteTextView.setFocusableInTouchMode(isReadOnly);
	}

	public boolean isReadOnly() {
		return isReadOnly;
	}

	public void setAdapter(ConfigAdapter baseAdapter) {
		mAutoCompleteTextView.setAdapter(baseAdapter);
	}

	public void showDropDown() {
		mAutoCompleteTextView.showDropDown();
	}

	public void setError(String error) {
		mAutoCompleteTextView.setError(error);
	}

	private OnFocusChangeListener mFocusChange;

	@Override
	public void setOnFocusChangeListener(OnFocusChangeListener l) {
		mFocusChange = l;
	}

	public void setOnItemClickListener(OnItemClickListener itemClickListener) {
		mAutoCompleteTextView.setOnItemClickListener(itemClickListener);
	}
}